home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / UTILITY1 / MSWSRC35.ZIP / DIB.CPP < prev    next >
C/C++ Source or Header  |  1993-10-02  |  14KB  |  456 lines

  1.  
  2. //-----------------------------------------------------------------------------
  3. // DIB.C
  4. //
  5. // This is a collection of useful DIB manipulation/information gathering
  6. // functions.  Many functions are supplied simply to take the burden
  7. // of taking into account whether a DIB is a Win30 style or OS/2 style
  8. // DIB away from the application.
  9. //
  10. // The functions in this module assume that the DIB pointers or handles
  11. // passed to them point to a block of memory in one of two formats:
  12. //
  13. //       a) BITMAPINFOHEADER + color table + DIB bits (3.0 style DIB)
  14. //       b) BITMAPCOREHEADER + color table + DIB bits (OS/2 PM style)
  15. //
  16. // The SDK Reference, Volume 2 describes these data structures.
  17. //
  18. // A number of functions in this module were lifted from SHOWDIB,
  19. // and modified to handle OS/2 DIBs.
  20. //
  21. // The functions in this module could be streamlined (made faster and
  22. // smaller) by removing the OS/2 DIB specific code, and assuming all
  23. // DIBs passed to it are Win30 style DIBs.  The DIB file reading code
  24. // would need to be modified to always convert DIBs to Win30 style
  25. // DIBs.  The only reason this isn't done in DIBView is because DIBView
  26. // was written to test display and printer drivers (which are supposed
  27. // to support OS/2 DIBs wherever they support Win30 style DIBs).  SHOWDIB
  28. // is a great example of how to go about doing this.
  29. //-----------------------------------------------------------------------------
  30.  
  31.  
  32. #include "allwind.h"
  33. #include "dib.h"
  34.  
  35. #define PALVERSION 0x300
  36.  
  37. extern LPSTR FindDIBBits (LPSTR lpbi);
  38. extern WORD DIBNumColors (LPSTR lpbi);
  39. extern WORD PaletteSize (LPSTR lpbi);
  40. extern DWORD DIBHeight (LPSTR lpDIB);
  41. extern DWORD DIBWidth (LPSTR lpDIB);
  42. extern HBITMAP DIBToBitmap (HANDLE hDIB, HPALETTE hPal);
  43. extern void InitBitmapInfoHeader (LPBITMAPINFOHEADER lpBmInfoHdr,DWORD dwWidth,DWORD dwHeight,int nBPP);
  44. extern HANDLE BitmapToDIB (HBITMAP hBitmap, HPALETTE hPal);
  45.  
  46. //---------------------------------------------------------------------
  47. //
  48. // Function:   FindDIBBits
  49. //
  50. // Purpose:    Given a pointer to a DIB, returns a pointer to the
  51. //             DIB's bitmap bits.
  52. //
  53. // Parms:      lpbi == pointer to DIB header (either BITMAPINFOHEADER
  54. //                       or BITMAPCOREHEADER)
  55. //
  56. // History:   Date      Reason
  57. //             6/01/91  Created
  58. //
  59. //---------------------------------------------------------------------
  60.  
  61. LPSTR FindDIBBits (LPSTR lpbi)
  62. {
  63.    return (lpbi + *(LPDWORD)lpbi + PaletteSize (lpbi));
  64. }
  65.  
  66.  
  67.  
  68.  
  69. //---------------------------------------------------------------------
  70. //
  71. // Function:   DIBNumColors
  72. //
  73. // Purpose:    Given a pointer to a DIB, returns a number of colors in
  74. //             the DIB's color table.
  75. //
  76. // Parms:      lpbi == pointer to DIB header (either BITMAPINFOHEADER
  77. //                       or BITMAPCOREHEADER)
  78. //
  79. // History:   Date      Reason
  80. //             6/01/91  Created
  81. //
  82. //---------------------------------------------------------------------
  83.  
  84. WORD DIBNumColors (LPSTR lpbi)
  85. {
  86.    WORD wBitCount;
  87.  
  88.  
  89.       // If this is a Windows style DIB, the number of colors in the
  90.       //  color table can be less than the number of bits per pixel
  91.       //  allows for (i.e. lpbi->biClrUsed can be set to some value).
  92.       //  If this is the case, return the appropriate value.
  93.  
  94.    if (IS_WIN30_DIB (lpbi))
  95.       {
  96.       DWORD dwClrUsed;
  97.  
  98.       dwClrUsed = ((LPBITMAPINFOHEADER) lpbi)->biClrUsed;
  99.  
  100.       if (dwClrUsed)
  101.          return (WORD) dwClrUsed;
  102.       }
  103.  
  104.  
  105.       // Calculate the number of colors in the color table based on
  106.       //  the number of bits per pixel for the DIB.
  107.  
  108.    if (IS_WIN30_DIB (lpbi))
  109.       wBitCount = ((LPBITMAPINFOHEADER) lpbi)->biBitCount;
  110.    else
  111.       wBitCount = ((LPBITMAPCOREHEADER) lpbi)->bcBitCount;
  112.  
  113.    switch (wBitCount)
  114.       {
  115.       case 1:
  116.          return 2;
  117.  
  118.       case 4:
  119.          return 16;
  120.  
  121.       case 8:
  122.          return 256;
  123.  
  124.       default:
  125.          return 0;
  126.       }
  127. }
  128.  
  129.  
  130.  
  131.  
  132.  
  133. //---------------------------------------------------------------------
  134. //
  135. // Function:   PaletteSize
  136. //
  137. // Purpose:    Given a pointer to a DIB, returns number of bytes
  138. //             in the DIB's color table.
  139. //
  140. // Parms:      lpbi == pointer to DIB header (either BITMAPINFOHEADER
  141. //                       or BITMAPCOREHEADER)
  142. //
  143. // History:   Date      Reason
  144. //             6/01/91  Created
  145. //
  146. //---------------------------------------------------------------------
  147.  
  148. WORD PaletteSize (LPSTR lpbi)
  149. {
  150.    if (IS_WIN30_DIB (lpbi))
  151.       return (DIBNumColors (lpbi) * sizeof (RGBQUAD));
  152.    else
  153.       return (DIBNumColors (lpbi) * sizeof (RGBTRIPLE));
  154. }
  155.  
  156.  
  157.  
  158.  
  159. //---------------------------------------------------------------------
  160. //
  161. // Function:   DIBHeight
  162. //
  163. // Purpose:    Given a pointer to a DIB, returns its height.  Note
  164. //             that it returns a DWORD (since a Win30 DIB can have
  165. //             a DWORD in its height field), but under Win30, the
  166. //             high order word isn't used!
  167. //
  168. // Parms:      lpDIB == pointer to DIB header (either BITMAPINFOHEADER
  169. //                       or BITMAPCOREHEADER)
  170. //
  171. // History:   Date      Reason
  172. //             6/01/91  Created
  173. //
  174. //---------------------------------------------------------------------
  175.  
  176. DWORD DIBHeight (LPSTR lpDIB)
  177. {
  178.    LPBITMAPINFOHEADER lpbmi;
  179.    LPBITMAPCOREHEADER lpbmc;
  180.  
  181.    lpbmi = (LPBITMAPINFOHEADER) lpDIB;
  182.    lpbmc = (LPBITMAPCOREHEADER) lpDIB;
  183.  
  184.    if (lpbmi->biSize == sizeof (BITMAPINFOHEADER))
  185.       return lpbmi->biHeight;
  186.    else
  187.       return (DWORD) lpbmc->bcHeight;
  188. }
  189.  
  190.  
  191.  
  192. //---------------------------------------------------------------------
  193. //
  194. // Function:   DIBWidth
  195. //
  196. // Purpose:    Given a pointer to a DIB, returns its width.  Note
  197. //             that it returns a DWORD (since a Win30 DIB can have
  198. //             a DWORD in its width field), but under Win30, the
  199. //             high order word isn't used!
  200. //
  201. // Parms:      lpDIB == pointer to DIB header (either BITMAPINFOHEADER
  202. //                       or BITMAPCOREHEADER)
  203. //
  204. // History:   Date      Reason
  205. //             6/01/91  Created
  206. //
  207. //---------------------------------------------------------------------
  208.  
  209. DWORD DIBWidth (LPSTR lpDIB)
  210. {
  211.    LPBITMAPINFOHEADER lpbmi;
  212.    LPBITMAPCOREHEADER lpbmc;
  213.  
  214.    lpbmi = (LPBITMAPINFOHEADER) lpDIB;
  215.    lpbmc = (LPBITMAPCOREHEADER) lpDIB;
  216.  
  217.    if (lpbmi->biSize == sizeof (BITMAPINFOHEADER))
  218.       return lpbmi->biWidth;
  219.    else
  220.       return (DWORD) lpbmc->bcWidth;
  221. }
  222.  
  223.  
  224.  
  225.  
  226. //---------------------------------------------------------------------
  227. //
  228. // Function:   DIBToBitmap
  229. //
  230. // Purpose:    Given a handle to global memory with a DIB spec in it,
  231. //             and a palette, returns a device dependent bitmap.  The
  232. //             The DDB will be rendered with the specified palette.
  233. //
  234. // Parms:      hDIB == HANDLE to global memory containing a DIB spec
  235. //                     (either BITMAPINFOHEADER or BITMAPCOREHEADER)
  236. //             hPal == Palette to render the DDB with.  If it's NULL,
  237. //                     use the default palette.
  238. //
  239. // History:   Date      Reason
  240. //             6/01/91  Created
  241. //
  242. //---------------------------------------------------------------------
  243.  
  244. HBITMAP DIBToBitmap (HANDLE hDIB, HPALETTE hPal)
  245. {
  246.    LPSTR    lpDIBHdr, lpDIBBits;
  247.    HBITMAP  hBitmap;
  248.    HDC      hDC;
  249.    HPALETTE hOldPal = NULL;
  250.  
  251.    if (!hDIB)
  252.       return NULL;
  253.  
  254.    lpDIBHdr  = (char *)GlobalLock (hDIB);
  255.    lpDIBBits = FindDIBBits (lpDIBHdr);
  256.    hDC       = GetDC (NULL);
  257.  
  258.    if (!hDC)
  259.       {
  260.       GlobalUnlock (hDIB);
  261.       return NULL;
  262.       }
  263.  
  264.    if (hPal)
  265.       hOldPal = SelectPalette (hDC, hPal, FALSE);
  266.  
  267.    RealizePalette (hDC);
  268.  
  269.    hBitmap = CreateDIBitmap (hDC,
  270.                              (LPBITMAPINFOHEADER) lpDIBHdr,
  271.                              CBM_INIT,
  272.                              lpDIBBits,
  273.                              (LPBITMAPINFO) lpDIBHdr,
  274.                              DIB_RGB_COLORS);
  275.  
  276.    if (!hBitmap)
  277.         MessageBox(MainHWindow, "Not Enough Memory", "Error", M